<html>
<head><meta charset="utf-8"><title>Pointers to overlapping arrays · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html">Pointers to overlapping arrays</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="239261450"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239261450" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Frank Steffahn <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239261450">(May 18 2021 at 14:20)</a>:</h4>
<p>This kind of code seems problematic, right?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">array</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">array</span><span class="p">[</span><span class="mi">0</span><span class="o">..</span><span class="p">].</span><span class="n">as_mut_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[0..3]`</span>
<span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">array</span><span class="p">[</span><span class="mi">1</span><span class="o">..</span><span class="p">].</span><span class="n">as_mut_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[1..4]`</span>

<span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">ptr</span>::<span class="n">swap</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="fm">dbg!</span><span class="p">(</span><span class="o">&amp;</span><span class="n">array</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>My understanding is that the above should probably be UB and that something like the following would be how it’s done properly</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">array</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">pointer</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="kt">i32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">array</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">();</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pointer</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">i32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[0..3]`</span>
<span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pointer</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">i32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[1..4]`</span>

<span class="w">    </span><span class="n">ptr</span>::<span class="n">swap</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="fm">dbg!</span><span class="p">(</span><span class="o">&amp;</span><span class="n">array</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>How could this be written nicer? I suppose with some unstable API something like the following should be a sound and perhaps reasonable approach, right?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#![feature(slice_ptr_get)]</span><span class="w"></span>
<span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">array</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">slice_pointer</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">i32</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">array</span><span class="p">;</span><span class="w"></span>

<span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">slice_pointer</span><span class="p">.</span><span class="n">get_unchecked_mut</span><span class="p">(</span><span class="mi">0</span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[0..3]`</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">slice_pointer</span><span class="p">.</span><span class="n">get_unchecked_mut</span><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[1..4]`</span>

<span class="w">    </span><span class="n">ptr</span>::<span class="n">swap</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="fm">dbg!</span><span class="p">(</span><span class="o">&amp;</span><span class="n">array</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>I have no idea about if indexing arrays with ranges works with <code>ptr::addr_of_mut</code>. E.g. is the following sound?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">array</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"></span>

<span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span>::<span class="n">addr_of_mut</span><span class="o">!</span><span class="p">(</span><span class="n">array</span><span class="p">[</span><span class="mi">0</span><span class="o">..</span><span class="p">])</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[0..3]`</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span>::<span class="n">addr_of_mut</span><span class="o">!</span><span class="p">(</span><span class="n">array</span><span class="p">[</span><span class="mi">1</span><span class="o">..</span><span class="p">])</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[1..4]`</span>

<span class="w">    </span><span class="n">ptr</span>::<span class="n">swap</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="fm">dbg!</span><span class="p">(</span><span class="o">&amp;</span><span class="n">array</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>Can anyone confirm my intuition and answer the last question? By the way, the very first code example comes from <a href="https://doc.rust-lang.org/nightly/std/ptr/fn.swap.html#examples">here</a>.</p>



<a name="239262177"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239262177" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239262177">(May 18 2021 at 14:25)</a>:</h4>
<p>I agree with you</p>



<a name="239272114"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239272114" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239272114">(May 18 2021 at 15:20)</a>:</h4>
<p>Oh damn, that example in the docs is indeed so pre-SB <span aria-label="scream" class="emoji emoji-1f631" role="img" title="scream">:scream:</span></p>



<a name="239272380"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239272380" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239272380">(May 18 2021 at 15:21)</a>:</h4>
<p>what's SB?</p>



<a name="239272486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239272486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239272486">(May 18 2021 at 15:22)</a>:</h4>
<p>Stacked Borrows, sorry</p>



<a name="239272524"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239272524" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239272524">(May 18 2021 at 15:22)</a>:</h4>
<p>do'h of course</p>



<a name="239273074"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239273074" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239273074">(May 18 2021 at 15:25)</a>:</h4>
<p>The third snippet looks like the most sensible approach (besides the second one, which is the one I personally go for to make sure things are fine).<br>
Regarding the last snippet, I've personally found <code>addr_of_mut!</code> to be a bit ill-defined in that regard:</p>
<ul>
<li>Given <code>p: &amp;Struct</code>, <code>addr_of!( (*p).field )</code> yields a pointer with provenance over that <code>field</code> <em>only</em>;</li>
<li>Given <code>p: *const Struct</code>, <code>addr_of!( (*p).field )</code> just offsets the original pointer, preserving its original provenance.<br>
In that regard, I don't know if <code>addr_of!</code> on a place that outside the macro is necessarily accessed through a <code>&amp;mut</code>-reference (the usage of <code>[…]</code> indexing, I mean) asserts unicity of the access to that place there and then <span aria-label="shrug" class="emoji emoji-1f937" role="img" title="shrug">:shrug:</span> I'd personally not risk it until the SB-<code>addr_of{,_mut}!</code> interaction is better clarified / documented</li>
</ul>



<a name="239273667"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239273667" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239273667">(May 18 2021 at 15:29)</a>:</h4>
<p>Okay, the following compiles and runs fine:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span>::<span class="n">core</span>::<span class="n">ptr</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">array</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"></span>

<span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">array</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">array</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span>::<span class="n">addr_of_mut</span><span class="o">!</span><span class="p">((</span><span class="o">*</span><span class="n">array</span><span class="p">)[</span><span class="mi">0</span><span class="o">..</span><span class="p">])</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[0..3]`</span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span>::<span class="n">addr_of_mut</span><span class="o">!</span><span class="p">((</span><span class="o">*</span><span class="n">array</span><span class="p">)[</span><span class="mi">1</span><span class="o">..</span><span class="p">])</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[1..4]`</span>

<span class="w">    </span><span class="n">ptr</span>::<span class="n">swap</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="fm">dbg!</span><span class="p">(</span><span class="o">&amp;</span><span class="n">array</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<ul>
<li><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=f625834986e278ba0b9f2921c23c0bac">Playground</a></li>
</ul>
<p>This one I'd be more confident about it not asserting lack of aliasing when indexing <span aria-label="smile" class="emoji emoji-1f642" role="img" title="smile">:smile:</span></p>



<a name="239301377"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239301377" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239301377">(May 18 2021 at 18:20)</a>:</h4>
<p><span class="user-mention" data-user-id="280891">@Frank Steffahn</span> I don't think your first example is UB - the <code>ptr::swap</code> docs explicitly state that overlapping is allowed</p>



<a name="239310268"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239310268" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Frank Steffahn <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239310268">(May 18 2021 at 19:17)</a>:</h4>
<p><span class="user-mention" data-user-id="125294">@Aaron Hill</span> </p>
<p>To be clear, I see UB in the code <em>mostly before</em> the <code>ptr::swap</code> call. The <code>ptr::swap</code> is necessary for UB, but really it’s just a place where both mutable pointers are used; in particulat it’s a place where <code>x</code> is used and dereferenced.</p>
<p>The point is that <code>.as_mut_ptr</code> is a method on <code>&amp;mut [i32]</code>, so that</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">array</span><span class="p">[</span><span class="mi">0</span><span class="o">..</span><span class="p">].</span><span class="n">as_mut_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[0..3]`</span>
</code></pre></div>
<p>does</p>
<ol>
<li>create a <code>&amp;mut [i32]</code> slice reference pointing to <code>array[0..]</code>, and</li>
<li>turn that reference into <code>*mut [i32]</code> and then that is further converted into <code>*mut [i32; 3]</code>.</li>
</ol>
<p>Similarly,</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">array</span><span class="p">[</span><span class="mi">1</span><span class="o">..</span><span class="p">].</span><span class="n">as_mut_ptr</span><span class="p">()</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">u32</span><span class="p">;</span><span class="w"> </span><span class="mi">3</span><span class="p">];</span><span class="w"> </span><span class="c1">// this is `array[1..4]`</span>
</code></pre></div>
<p>does</p>
<ol>
<li>create a <code>&amp;mut [i32]</code> slice reference pointing to <code>array[1..]</code>, and</li>
<li>turn that reference into <code>*mut [i32]</code> and then that is further converted into <code>*mut [i32; 3]</code>.</li>
</ol>
<p>The point is that as far as I understand stacked borrows, the creation of the mutable borrow of <code>array[1..]</code> <em>invalidates</em> all pointers derived from the previous mutable borrow of <code>array[0..]</code>, which includes the pointer <code>x</code>. So that any later usage of <code>x</code> later such as in <code>ptr::swap</code> is UB.  I’m very aware of what the <code>ptr::swap</code> docs say, in fact, this code example comes from said docs which provide it (and thus implicitly claim it <em>isn’t</em> UB), so the <code>ptr::swap</code> docs are in fact to be  scrutinized here. Furthermore, in case you didn’t notice, <em>all</em> of my examples feature a call to <code>ptr::swap</code> with overlapping pointers; even the code examples which I think <em>aren’t</em> UB.</p>
<hr>
<p>To throw in dome citation of the docs, <code>ptr::swap</code> mentions</p>
<blockquote>
<p>Both <code>x</code> and <code>y</code> must be <a href="https://doc.rust-lang.org/nightly/std/ptr/index.html#safety">valid</a> for both reads and writes.</p>
</blockquote>
<p>and the linked definition of pointer validity says</p>
<blockquote>
<p>The result of casting a reference to a pointer is valid for as long as the underlying object is live and no reference (just raw pointers) is used to access the same memory.</p>
</blockquote>



<a name="239311488"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239311488" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239311488">(May 18 2021 at 19:26)</a>:</h4>
<p>By the way Miri (with <code>-Zmiri-track-raw-pointers</code>) agrees that this is UB</p>



<a name="239401240"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Pointers%20to%20overlapping%20arrays/near/239401240" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Frank Steffahn <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Pointers.20to.20overlapping.20arrays.html#239401240">(May 19 2021 at 10:43)</a>:</h4>
<p>Here’s a PR bringing the second approach into the documentation <a href="https://github.com/rust-lang/rust/issues/85464">#85464</a>.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>